
#include "mPlane.h"


mPlane::mPlane(void)
{
	Intercept = 0.0f;
}

mPlane::mPlane(const mPlane &a)
{
	Normal = a.Normal;
	Intercept = a.Intercept;
}

mPlane::mPlane(const mVector3 & n, float inter)
{
	Normal = n;
	Intercept = inter;
}

mPlane::mPlane(const mVector3 & v0, const mVector3 & v1, const mVector3 & v2)
{
	Normal = crossProduct((v1 - v0), (v2 - v0));
	Normal.normalize();

	Intercept = -dotProduct(Normal, v0);
}

mPlane::~mPlane(void)
{
}


mPlane &mPlane::operator =(const mPlane &a)
{
	Normal = a.Normal;
	Intercept = a.Intercept;
	return *this;
}

bool mPlane::operator ==(const mPlane &a) const
{
	return Normal == a.Normal && Intercept == a.Intercept;
}

bool mPlane::operator !=(const mPlane &a) const
{
	return Normal != a.Normal || Intercept != a.Intercept;
}

mPlane mPlane::operator -() const
{
	return mPlane(-Normal, -Intercept);
}


bool mPlane::Intersect3(const mPlane & p2, const mPlane & p3, mVector3 & result)
{
	float denominator = dotProduct(Normal, crossProduct(p2.Normal, p3.Normal));
											//scalar triple product of normals
	if(denominator == 0.0f) return false;	//no intersection

	mVector3 temp1, temp2, temp3;
	temp1 = crossProduct(p2.Normal, p3.Normal) * Intercept;
	temp2 = crossProduct(p3.Normal, Normal) * p2.Intercept;
	temp3 = crossProduct(Normal, p2.Normal) * p3.Intercept;

	result = (temp1 + temp2 + temp3) / (-denominator);

	return true;
}

float mPlane::GetDistance(const mVector3 & point) const
{
	return point.X * Normal.X + point.Y * Normal.Y + point.Z * Normal.Z + Intercept;
}

int mPlane::ClassifyPoint(const mVector3 & point) const
{
	float distance = point.X * Normal.X + point.Y * Normal.Y + point.Z * Normal.Z + Intercept;

	if(distance > EPSILON)	//==0.0f is too exact, give a bit of room
		return POINT_IN_FRONT_OF_PLANE;
	
	if(distance < -EPSILON)
		return POINT_BEHIND_PLANE;

	return POINT_ON_PLANE;	//otherwise
}

mPlane mPlane::lerp(const mPlane & p2, float factor)
{
	mPlane result;
	result.Normal = Normal * (1.0f - factor) + p2.Normal * factor;
	result.Normal.normalize();

	result.Intercept = Intercept * (1.0f - factor) + p2.Intercept * factor;

	return result;
}

